// i.r(t), i.d(t, { default: () => LabelDataModule })
import Logger from "../utils/Logger"
import Module from "./Module"
import SymbolList from "../SymbolList"

import DataSyncStore from "../storage/DataSyncStore"
import MapMonitor from "../collection/MapMonitor"
import aggregationTypeEnum from "../enum/aggregationType.enum"
import LabelData from "../data/LabelData"
import Store from "../storage/Store"
import { CollectionSync } from "../storage/DataSync"
import b from "../math/19674"

import funcUtil from "../utils/func.util"
import Label from "../object/Label"
import { dateISO, getDate } from "../utils/date.util"
import storageTypeEnum from "../enum/storageType.enum"
import dataTypeEnum from "../enum/dataType.enum"
const _ = new Logger("label-serialization"),
  deserialize = e => {
    if (!e) return null
    const t = {}
    if (e)
      for (const i of Object.keys(e)) {
        const n = e[i]
        try {
          if (!n || !n.version || isNaN(Number.parseFloat(n.version)) || Number.parseFloat(n.version) < 3) continue
          const e = new Label()
          e.copy({
            floorId: "number" == typeof n.floorId ? String(n.floorId) : "",
            position: b.gj(n.position),
            sid: n.sid,
            text: n.text || "",
            visible: n.visible,
            roomId: n.roomId,
            created: getDate(n.created),
            modified: getDate(n.modified),
            version: n.version
          }),
            (t[n.sid] = e)
        } catch (e) {
          _.warn("Error parsing label data; not adding label: ", n)
        }
      }
    return t
  },
  x = (e, t) => {
    const i = {},
      n = funcUtil.deepCopy(e)
    funcUtil.merge(n, t)
    for (const e of Object.keys(n)) {
      const t = n[e]
      if (!t) continue
      const s = parseInt(t.floorId, 10)
      if (isNaN(s)) throw new Error(`Failed to serialize unsupported floor ID '${t.floorId}'`)
      ;(i[t.sid] = {
        floorId: s,
        position: t.position,
        sid: t.sid,
        text: t.text,
        visible: t.visible,
        roomId: t.roomId,
        created: dateISO(t.created),
        modified: dateISO(t.modified),
        version: t.version
      }),
        (i[t.sid].position = b.gj(t.position))
    }
    return i
  },
  A = (e, t) => {
    const i = [],
      n = funcUtil.deepCopy(e)
    funcUtil.merge(n, t)
    for (const e of Object.keys(n)) {
      const t = n[e]
      if (!t) continue
      const s = parseInt(t.floorId, 10)
      if (isNaN(s)) throw new Error(`Failed to serialize unsupported floor ID '${t.floorId}'`)
      i.push({
        floorId: s,
        position: b.gj(t.position),
        sid: t.sid,
        text: t.text,
        visible: t.visible,
        roomId: t.roomId,
        created: dateISO(t.created),
        modified: dateISO(t.modified),
        version: t.version
      })
    }
    return i
  }
const H = new Logger("label-data")
export default class LabelDataModule extends Module {
  monitor: any
  config: any
  engine: any
  market: any
  store: DataSyncStore
  labelData: any
  constructor() {
    super(...arguments), (this.name = "label-data"), (this.monitor = null)
  }
  async init(e, t) {
    ;(this.config = Object.assign(Object.assign({}, e), {
      readonly: !("readonly" in e) || !!e.readonly,
      storageProvider: e.storageProvider || storageTypeEnum.JSONSTORE
    })),
      (this.engine = t),
      (this.market = t.market),
      (this.store = this.configureStorage())
    const i = (await this.store.read()) || {}
    const s = await t.getModuleBySymbol(SymbolList.MESH_QUERY)
    for (const e of Object.values(i)) s.inferMeshIdsFromPoint(e, e["position"])
    ;(this.labelData = t.market.tryGetData(LabelData) || new LabelData(i)),
      this.market.register(this, LabelData, this.labelData),
      this.config.readonly || this.configureSaving(this.store, this.labelData)
  }
  configureStorage() {
    const { modelId, baseUrl, queue } = this.config
    H.info(`Loading Labels from ${this.config.storageProvider}`)
    const path = `${baseUrl}/scene-portal/${modelId}/api/labels`
    const store = new Store.ReadOnlyStore({ queue, path, deserialize })
    const sync = new CollectionSync({ publishStores: [store] })
    return new DataSyncStore(sync, {
      dataType: dataTypeEnum.LABELS,
      engine: this.engine
    })
  }
  configureSaving(e, t) {
    this.monitor = new MapMonitor(t.getCollection(), { aggregationType: aggregationTypeEnum.Manual, shallow: !0 }, this.engine)
    this.store instanceof DataSyncStore && e.addMonitor(this.monitor)
  }

  onUpdate() {}
}
